package com.gopay.gass.base.dao;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.type.NullableType;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;

public interface BaseReadDAO <T extends Serializable, Pk extends Serializable> {

    /**
     * 通过实例属性查询
     * 
     * @param entity
     */
    List<T> findByExample(T entity);

    /**
     * 查找数据
     * 
     * @param id
     *            主键
     * @return
     */
    T find(Class<T> entity, Pk id);

    /**
     * 基于criteria的查询
     * 
     * @param criteria
     * @return
     */
    List<T> findByCriteria(DetachedCriteria criteria);

    /**
     * 基于criteria的查询
     * 
     * @param criteria
     * @param pageNo
     * @param pageSize
     * @return
     */
    List<T> findByCriteria(DetachedCriteria criteria, int pageNo, int pageSize);

    /**
     * 基于criteria的查询记录总数
     * 
     * @param criteria
     * @return
     */
    int findCountByCriteria(DetachedCriteria criteria);

    /**
     * 通过SQLScalar查询
     * 
     * @param sql
     * @param scalarSet
     * @return
     */
    List<T> findBySqlScalar(final String sql, final Set<String> scalarSet);

    /**
     * 通过SQLScalar查询
     * 
     * @param sql
     * @param pageNo
     * @param pageSize
     * @param scalarSet
     * @return
     */
    List<T> findBySqlScalar(final String sql, final int pageNo, final int pageSize, final Set<String> scalarSet);

    /**
     * 查询T表所有数据
     * 
     * @param entityClass
     * @return
     */
    List<T> findAll(Class<T> entityClass);

    /**
     * 通过HQL查询
     * 
     * @param hql
     * @param param
     * @return
     */
    List<T> findByHql(final String hql, final Map<String, Object> param);

    /**
     * 通过HQL查询
     * 
     * @param hql
     * @param param
     * @param pageIndex
     * @param pageSize
     * @return
     */
    List<T> findByHql(final String hql, final Map<String, Object> param, final int pageIndex, final int pageSize);

    /**
     * 通过SQL查询
     * 
     * @param sql
     * @return
     */
    List<T> findBySql(final String sql);

    /**
     * 通过SQL查询
     * 
     * @param sql
     * @param param
     * @return
     */
    List<T> findBySql(final String sql, final Map<String, Object> param);

    /**
     * 通过SQL查询
     * 
     * @param sql
     * @param pageNo
     * @param pageSize
     * @return
     */
    List<T> findBySql(final String sql, final int pageNo, final int pageSize);

    /**
     * 通过SQL查询
     * 
     * @param sql
     * @param param
     * @param pageNo
     * @param pageSize
     * @return
     */
    List<T> findBySql(final String sql, final Map<String, Object> param, final int pageNo, final int pageSize);
    
    int findCountByHql(final String hql, Map<String, Object> params);
    
    int findCountBySql(final String sql);
    int findCountBySql(final String sql, Map<String, Object> params);
    
    /**
     * 根据SQL语句查询记录总数之hibernate版
     * 
     * @param sql
     * @param param
     * @return
     */
    public int findCountBySqlOfHibernate(final String sql, final Map<String, Object> param);
    
    /**
     * 通过SQLScalar查询
     * 
     * @param sql
     * @param pageNo
     * @param pageSize
     * @param scalarSet
     * @param target
     * @return
     */
    List<T> findBySqlScalar(final String sql, final int pageNo, final int pageSize,
                            final Map<String, NullableType> scalarMap, final Class<T> target, final Map<String, Object> param);

    /**
     * 查询指定记录
     * 
     * @param sql
     * @param scalarMap
     * @param target
     * @param param
     * @return
     */
    T findBySqlScalar(final String sql, final Map<String, NullableType> scalarMap, final Class<T> target,
                      final Map<String, Object> param);

    String getNextId(final String sequence);

    /**
     * 得到序列下一个值,不足bit补0
     * 
     * @param sequence
     * @param bit
     * @return
     */
    String getNextIdFillZero(final String sequence, final int bit);
    
    /**
     * 执行存储过程
     * @param procedureName 存储过程函数名
     * @param inputList 有序输入参数
     * @param outTypeList 有序输出参数类型 Types.VARCHAR..
     * @return 返回存储过程执行结果集
     */
    public List<Object> executeProcedure(final String procedureName, final List<Object> inputList, final List<Integer> outTypeList);
}
